﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Animation;
using MimiDouban.Abstract;
using MimiDouban.Abstract.Beans;
using doubanloginDll8;
using System.Windows.Media.Effects;
using MimiDouban.UI.SkinManager;
using MimiDouban.Extention;
using System.Threading;

namespace MimiDouban
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class MainWindow : Window, IMainUI
    {
        private double volume = 0.50;
        private DoubanChannel[] channels;
        private Storyboard channelStoryBoard;
        private bool showMainPanel = true;
        private bool showChannelPanel = false;
        private bool showLoginPanel = false;
        private double channelListTargetTop = 30;
        private bool isPaused = false;
        private DoubanSong currentSong = null;
        private ControlStatus likeStatus;
        private ControlStatus dislikeStatus;
        private System.Windows.Forms.NotifyIcon notifyIcon;
        private bool isFirstSong = true;
        private bool draggingVolume = false;
        private Point lastPosition;
        private Skin currentSkin;

        private BitmapImage nextImg;

        private bool isShowMenu = false;
        

        public double Volume
        {
            get
            {
                return volume;
            }
        }

        //界面用到的状态变量
        public double VolumeAngle
        {
            get
            {
                return 150 + 240 * volume;
            }
        }

        public MainWindow()
        {
            InitializeComponent();
            AddNotifyIconSupport();
            this.AddHandler(Window.MouseWheelEvent, new MouseWheelEventHandler(this.gridAdd_MouseWheel), true);
            gridTitle.AddHandler(Grid.MouseLeftButtonDownEvent, new MouseButtonEventHandler(this.gridTitle_MouseLeftButtonDown), true);
            gridMin.AddHandler(Grid.MouseLeftButtonDownEvent, new MouseButtonEventHandler(this.gridMin_MouseLeftButtonUp), true);
            updateAngle();
        }

        #region MainUI Members

        public void start()
        {

            initUserSetting();
            this.Show();
        }

        private void initUserSetting()
        {
            //读取上一次使用的皮肤
            string skinId = DataStore.getInstance().getString("skinId");
            Skin newSkin = SkinManager.getInstance().getSkinWithID(skinId);
            this.setSkin(newSkin);


            //读取上一次窗口的位置
            double left = DataStore.getInstance().getDouble("left");

            if (!left.Equals(double.NaN))
            {
                this.Left = left;
            }
            double top = DataStore.getInstance().getDouble("top");
            if (!top.Equals(double.NaN))
            {
                this.Top = top;
            }
        }

        public DoubanChannel[] Channels
        {
            get { return channels; }
            set
            {
                channels = value;
                this.showChannels();
            }
        }

        public void ShowSongInfo(DoubanSong song)
        {
            currentSong = song;
            txtAlbumName.Text = "专辑： " + song.Albumtitle;
            txtNameArtist.Text = song.Title + " - " + song.Artist;
            txtAllTime.Text = "/ " + toTimeFormat(song.Length);

            if ("1".Equals(song.Like))
            {
                setLikeStatus(ControlStatus.Pressed);
            }
            else
            {
                setLikeStatus(ControlStatus.Enabled);
            }
            
            //开始下载图片
            imgAlbum.Source = new BitmapImage(new Uri(song.Picture));

            if (isFirstSong)
            {
                gridAlbum.MouseLeftButtonDown += new MouseButtonEventHandler(gridAlbum_MouseLeftButtonDown);

                hplDownload.Foreground = Resources["skinDownload"] as Brush;
                hplDownload.Click += new RoutedEventHandler(Download_Click);

                imgLoadingalbum.Source = new BitmapImage(new Uri("Resources/images/loaingalbum.png", UriKind.RelativeOrAbsolute));

                isFirstSong = false;
            }
        }

        public void ShowNextSong(DoubanSong song)
        {
            if (showChannelPanel)
            {
                txtBackToMain_MouseLeftButtonUp(null, null);
            }
            currentSong = song;
            Storyboard dimStoryboard = this.Resources["MainPanelDim"] as Storyboard;
            dimStoryboard.Begin();
        }

        public void ShowChannel(DoubanChannel channel)
        {
            if ("0".Equals(channel.ChannelId))//如果是私人频道
            {
                setDislikeStatus(ControlStatus.Enabled);
            }
            else
            {
                setDislikeStatus(ControlStatus.Disabled);
            }

            txtChannleName.Text = channel.ChannelName;
        }

        public void showTime(int min, int sec)
        {
            txtTime.Text = String.Format("{0:D2}:{1:D2}", min, sec);
        }

        public void showVolume(double volume)
        {
            this.volume = volume;
            updateAngle();
        }

        public void setLikeStatus(ControlStatus status)
        {
            this.likeStatus = status;
            if (status == ControlStatus.Enabled)
            {
                imgLike.Source = new BitmapImage(new Uri("Resources/images/like.png", UriKind.Relative));
                btnLike.ToolTip = "我喜欢";
            }
            else if (status == ControlStatus.Pressed)
            {
                imgLike.Source = new BitmapImage(new Uri("Resources/images/like_pressed.png", UriKind.Relative));
                btnLike.ToolTip = "取消我喜欢";
            }
        }

        public ControlStatus getLikeStatus()
        {
            return likeStatus;
        }

        public void setDislikeStatus(ControlStatus status)
        {
            this.dislikeStatus = status;
            if (status == ControlStatus.Enabled)
            {
                btnDislike.ToolTip = "不再播放";
            }
            else
            {
                btnDislike.ToolTip = "私人频道可用";
            }
        }

        public void setPauseStatus(bool paused)
        {
            this.isPaused = paused;

            if (paused)
            {
                imgPause.Source = new BitmapImage(new Uri("Resources/images/play.png", UriKind.Relative));
                ((BlurEffect)grid.Effect).Radius = 8;
            }
            else
            {
                imgPause.Source = new BitmapImage(new Uri("Resources/images/pause.png", UriKind.Relative));
                ((BlurEffect)grid.Effect).Radius = 0;
            }
        }

        public void showLogin()
        {
            txtLoginNote.Text = "";
            Storyboard switchFromChannelToLogin = ((Storyboard)this.Resources["switchFromChannelToLogin"]);
            switchFromChannelToLogin.Completed += new EventHandler(switchFromChannelToLogin_Completed);
            switchFromChannelToLogin.Begin();
            showLoginPanel = true;
            showChannelPanel = false;
        }

        public void showCurrentUser(string username)
        {
            txtLogin.Visibility = Visibility.Hidden;
            txtLogin.Text = "";
            txtCurrentUser.Text = username;
            txtCurrentUser.Visibility = Visibility.Visible;
        }

        public void showLoginBtn()
        {
            txtLogin.Visibility = Visibility.Visible;

            txtLogin.Text = "登录";
            txtCurrentUser.Visibility = Visibility.Hidden;
        }

        public void end()
        {
            string skinId = currentSkin.SkinId;
            if (this.WindowState == WindowState.Minimized)
            {
                this.Close();
            }
            else
            {
                Storyboard endStoryboard = this.Resources["OnWindowEnd"] as Storyboard;
                endStoryboard.Begin();
            }

            //记录当前SKin
            DataStore.getInstance().saveString("skinId", skinId);

            //记录当前窗口位置
            if (this.WindowState != WindowState.Minimized)
            {
                DataStore.getInstance().saveString("left", this.Left.ToString());
                DataStore.getInstance().saveString("top", this.Top.ToString());
            }
        }

        public event UIHandler UIStarted;
        public event ButtonClickHandler LikeClicked;
        public event ButtonClickHandler DisikeClicked;
        public event ButtonClickHandler NextClicked;
        public event ButtonClickHandler PauseClicked;
        public event ButtonClickHandler CloseClicked;
        public event ChannelChooseHandler ChannelChoosen;
        public event VolumeChangedHandler VolumeChanged;
        public event UserLoginHandler UserLogin;

        #endregion

        #region PrivateEventHandler

        private void newTextBlock_MouseLeave(object sender, MouseEventArgs e)
        {
            Color foreColor = new Color();
            foreColor.A = 0xAA;
            foreColor.B = 0xFF;
            foreColor.G = 0xFF;
            foreColor.R = 0xFF;
            Brush foreground = new SolidColorBrush(foreColor);
            ((TextBlock)sender).Foreground = foreground;
        }

        private void newTextBlock_MouseEnter(object sender, MouseEventArgs e)
        {
            Color foreColor = new Color();
            foreColor.A = 0xFF;
            foreColor.B = 0xFF;
            foreColor.G = 0xFF;
            foreColor.R = 0xFF;
            Brush foreground = new SolidColorBrush(foreColor);
            ((TextBlock)sender).Foreground = foreground;
        }

        private void newTextBlock_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (!showChannelPanel)
            {
                return;
            }
            TextBlock clickedItem = (TextBlock)sender;
            DoubanChannel ch = (DoubanChannel)clickedItem.Tag;

            if (ChannelChoosen != null)
            {
                ChannelChoosen.Invoke(Int32.Parse(ch.ChannelId));
            }
            //txtBackToMain_MouseLeftButtonUp(sender, e);
        }

        private void switchFromChannelToLogin_Completed(object sender, EventArgs e)
        {
            Grid.SetZIndex(gridLoginMainPanel, 10);
            Grid.SetZIndex(mainPanelChannel, 0);
        }

        private void gridTitle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ButtonState == MouseButtonState.Pressed)
            {
                this.DragMove();
            }
        }

        private void gridMin_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            this.WindowState = WindowState.Minimized;
        }

        private void gridAdd_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            if (showMainPanel)
            {
                volume = volume + (e.Delta / 40) * 1.0 / 100;
                if (volume < 0)
                {
                    volume = 0;
                }
                else if (volume > 1)
                {
                    volume = 1;
                }
                updateAngle();
                if (VolumeChanged != null)
                {
                    VolumeChanged.Invoke(volume);
                }
            }
        }

        private void MainPanelDim_Completed(object sender, EventArgs e)
        {
            ShowSongInfo(currentSong);
            Storyboard showStoryboard = this.Resources["MainPanelShow"] as Storyboard;
            showStoryboard.Begin();
        }

        private void OnWindowEnd_Completed(object sender, EventArgs e)
        {
            this.Close();
        }

        private void Border_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            if (!showChannelPanel)
            {
                return;
            }

            double maxTop = 30;
            double minTop = -30 * (this.channels.Length - 1) + 100;
            double oldTop = channelListTargetTop;
            double newTop = oldTop + (e.Delta) / 10;
            if (newTop > maxTop)
            {
                newTop = maxTop;
            }
            else if (newTop < minTop)
            {
                newTop = minTop;
            }
            channelListTargetTop = newTop;


            //获取当前位置
            Thickness from = spChannelList.Margin;
            Thickness to = new Thickness(from.Left, newTop, from.Right, from.Bottom);

            if (channelStoryBoard != null && channelStoryBoard.GetCurrentState() == ClockState.Active)
            {
                channelStoryBoard.Stop();
            }
            channelStoryBoard = new Storyboard();

            //创建动画
            ThicknessAnimation thicknessAnimation = new ThicknessAnimation(from, to, new Duration(TimeSpan.FromMilliseconds(100)));
            Storyboard.SetTarget(thicknessAnimation, spChannelList);
            Storyboard.SetTargetProperty(thicknessAnimation, new PropertyPath(StackPanel.MarginProperty));
            channelStoryBoard.Children.Add(thicknessAnimation);

            //动画播放
            channelStoryBoard.Begin();
        }

        private void btnChannel_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (showMainPanel)
            {
                ((Storyboard)this.Resources["switchToChannel"]).Begin();
                showMainPanel = false;
                showChannelPanel = true;
                Grid.SetZIndex(gridMainPanel, 0);
                Grid.SetZIndex(mainPanelChannel, 10);
                return;
            }
            if (showChannelPanel)
            {
                Storyboard switchToMain = ((Storyboard)this.Resources["switchToMainPannel"]);
                switchToMain.Completed += new EventHandler(switchToMain_Completed);
                switchToMain.Begin();
                showMainPanel = true;
                showChannelPanel = false;
                return;
            }
            if (showLoginPanel)
            {
                Storyboard switchToMain = ((Storyboard)this.Resources["switchFromLoginToMain"]);
                switchToMain.Completed += new EventHandler(switchToMain_Completed);
                switchToMain.Begin();
                showMainPanel = true;
                showLoginPanel = false;
                return;
            }
        }

        private void txtBackToMain_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (showChannelPanel)
            {
                Storyboard switchToMain = ((Storyboard)this.Resources["switchToMainPannel"]);
                switchToMain.Completed += new EventHandler(switchToMain_Completed);
                switchToMain.Begin();
                showMainPanel = true;
                showChannelPanel = false;
            }
        }

        private void switchToMain_Completed(object sender, EventArgs e)
        {
            Grid.SetZIndex(gridMainPanel, 10);
            Grid.SetZIndex(mainPanelChannel, 0);
        }

        private void txtLoginBackToMain_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (showLoginPanel)
            {
                Storyboard switchFromLoginToMain = ((Storyboard)this.Resources["switchFromLoginToMain"]);
                switchFromLoginToMain.Completed += new EventHandler(switchFromLoginToMain_Completed);
                switchFromLoginToMain.Begin();
                showMainPanel = true;
                showLoginPanel = false;
            }
        }

        private void switchFromLoginToMain_Completed(object sender, EventArgs e)
        {
            Grid.SetZIndex(gridMainPanel, 10);
            Grid.SetZIndex(gridLoginMainPanel, 0);
        }

        private void txtBackToMain_MouseLeave(object sender, MouseEventArgs e)
        {
            Color foreColor = new Color();
            foreColor.A = 0xAA;
            foreColor.B = 0xFF;
            foreColor.G = 0xFF;
            foreColor.R = 0xFF;
            Brush foreground = new SolidColorBrush(foreColor);
            ((TextBlock)sender).Foreground = foreground;
        }

        private void txtBackToMain_MouseEnter(object sender, MouseEventArgs e)
        {
            Color foreColor = new Color();
            foreColor.A = 0xFF;
            foreColor.B = 0xFF;
            foreColor.G = 0xFF;
            foreColor.R = 0xFF;
            Brush foreground = new SolidColorBrush(foreColor);
            ((TextBlock)sender).Foreground = foreground;
        }

        private void btnLike_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (this.LikeClicked != null)
            {
                this.LikeClicked.Invoke();
            }
        }

        private void btnDislike_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (dislikeStatus == ControlStatus.Enabled)
            {
                if (this.DisikeClicked != null)
                {
                    this.DisikeClicked.Invoke();
                }
                (this.Resources["btnDislikeOnMouseLeftButtonUp"] as Storyboard).Begin();
            }
        }

        private void btnDislike_MouseEnter(object sender, MouseEventArgs e)
        {
            if (dislikeStatus == ControlStatus.Enabled)
            {
                (this.Resources["btnDislikeOnMouseEnter"] as Storyboard).Begin();
            }
        }

        private void btnDislike_MouseLeave(object sender, MouseEventArgs e)
        {
            if (dislikeStatus == ControlStatus.Enabled)
            {
                (this.Resources["btnDislikeOnMouseLeave"] as Storyboard).Begin();
            }
        }

        private void btnDislike_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (dislikeStatus == ControlStatus.Enabled)
            {
                (this.Resources["btnDislikeOnMouseLeftButtonDown"] as Storyboard).Begin();
            }
        }

        private void btnNext_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (NextClicked != null)
            {
                NextClicked.Invoke();
            }
        }

        private void btnPause_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (this.PauseClicked != null)
            {
                this.PauseClicked.Invoke();
            }
        }

        private void btnLogin_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (showLoginPanel)
            {
                DoubanUser result = this.UserLogin.Invoke(txtUserName.Text, txtPassword.Password);
                if (result == null)
                {
                    txtLoginNote.Text = "登录失败，请检查";
                    return;
                }

                txtLogin.Visibility = Visibility.Hidden;
                txtLogin.Text = "";
                txtCurrentUser.Text = result.Username;
                txtCurrentUser.Visibility = Visibility.Visible;

                Storyboard switchFromLoginToMain = ((Storyboard)this.Resources["switchFromLoginToMain"]);
                switchFromLoginToMain.Completed += new EventHandler(switchFromLoginToMain_Completed);
                switchFromLoginToMain.Begin();
                showMainPanel = true;
                showLoginPanel = false;
            }
        }

        private void gridClose_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (this.CloseClicked != null)
            {
                this.CloseClicked.Invoke();
            }
        }

        private void OpenMainWindow_Click(object sender, EventArgs e)
        {
            this.WindowState = WindowState.Normal;
        }

        private void Exit_Click(object sender, EventArgs e)
        {
            this.WindowState = WindowState.Minimized;
            if (this.CloseClicked != null)
            {
                this.CloseClicked.Invoke();
            }
        }

        private void MainWindow_Closed(object sender, EventArgs e)
        {
            notifyIcon.Dispose();
        }

        private void MainWindow_StateChanged(object sender, EventArgs e)
        {
            if (this.WindowState == WindowState.Minimized)
            {
                notifyIcon.Visible = true;
                this.ShowInTaskbar = false;
            }
            else
            {
                notifyIcon.Visible = false;
                this.ShowInTaskbar = true;
            }
        }

        private void notifyIcon_Click(object sender, EventArgs e)
        {
            this.WindowState = WindowState.Normal;
        }

        private void WindowStart_Completed(object sender, EventArgs e)
        {
            if (this.UIStarted != null)
            {
                this.Dispatcher.BeginInvoke(this.UIStarted, new object[] { });
            }
        }

        private void Download_Click(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Process.Start(this.currentSong.Url);
        }

        private void gridChangeSkin_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Skin nextSkin = SkinManager.getInstance().getNextSkin();
            setSkin(nextSkin);
        }
        private void gridAlbum_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.douban.com" + this.currentSong.Album);
        }

        private void btnVolume_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            lastPosition = Mouse.GetPosition(btnVolume);
            draggingVolume = true;
            (this.Resources["beginDragVol"] as Storyboard).Begin();
        }

        private void btnVolume_MouseMove(object sender, MouseEventArgs e)
        {
            if (!draggingVolume)
            {
                return;
            }

            Point newPosition = Mouse.GetPosition(btnVolume);

            volume = volume + (newPosition.X - lastPosition.X) * 0.03;
            lastPosition = newPosition;

            if (volume < 0)
            {
                volume = 0;
            }
            else if (volume > 1)
            {
                volume = 1;
            }
            updateAngle();
            if (VolumeChanged != null)
            {
                VolumeChanged.Invoke(volume);
            }
        }

        private void btnVolume_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (draggingVolume)
            {
                draggingVolume = false;
                (this.Resources["endDragVol"] as Storyboard).Begin();
            }
        }

        private void btnVolume_MouseLeave(object sender, MouseEventArgs e)
        {
            btnVolume_MouseLeftButtonUp(sender, null);
        }

        private void txtLogin_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Storyboard switchFromLoginToMain = ((Storyboard)this.Resources["switchFromMainToLogin"]);
            switchFromLoginToMain.Begin();
            showMainPanel = false;
            showLoginPanel = true;
            Grid.SetZIndex(gridMainPanel, 0);
            Grid.SetZIndex(gridLoginMainPanel, 10);
        }

        private void txtCurrentUser_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            string currentDir = System.Environment.CurrentDirectory;
            System.Windows.Forms.SaveFileDialog sfd = new System.Windows.Forms.SaveFileDialog();
            sfd.Title = "保存音乐基因名片";
            sfd.Filter = "图片(*.jpg)|.jpg";
            sfd.FileName = "My MusicGene";
            if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string fileNmae = sfd.FileName;
                System.Drawing.Bitmap img = MusicGeneGenerator.getInstance().getMusicGene();
                img.Save(fileNmae);
            }
            System.Environment.CurrentDirectory = currentDir;
        }
        #endregion

        #region Private Functional Method

        private void showChannels()
        {
            spChannelList.Children.Clear();

            foreach (DoubanChannel ch in channels)
            {
                TextBlock newTextBlock = new TextBlock();
                Color foreColor = new Color();
                foreColor.A = 0xAA;
                foreColor.B = 0xFF;
                foreColor.G = 0xFF;
                foreColor.R = 0xFF;
                Brush foreground = new SolidColorBrush(foreColor);
                newTextBlock.Foreground = foreground;
                newTextBlock.HorizontalAlignment = HorizontalAlignment.Left;
                newTextBlock.Margin = new Thickness(150, 0, 0, 0);
                newTextBlock.Padding = new Thickness(5);
                newTextBlock.FontSize = 15;
                newTextBlock.FontFamily = new FontFamily("微软雅黑");
                newTextBlock.Height = 30;
                newTextBlock.Text = ch.ChannelName;
                newTextBlock.Tag = ch;

                newTextBlock.MouseLeftButtonUp += new MouseButtonEventHandler(newTextBlock_MouseLeftButtonUp);
                newTextBlock.MouseEnter += new MouseEventHandler(newTextBlock_MouseEnter);
                newTextBlock.MouseLeave += new MouseEventHandler(newTextBlock_MouseLeave);

                spChannelList.Children.Add(newTextBlock);
            }
        }

        private void updateAngle()
        {
            RotateTransform rotateTransform = new RotateTransform(VolumeAngle);
            imgPointer.RenderTransform = rotateTransform;
        }

        private void AddNotifyIconSupport()
        {
            notifyIcon = new System.Windows.Forms.NotifyIcon();
            notifyIcon.Icon = new System.Drawing.Icon("Resources/icon/icon_small.ico");
            notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu();
            notifyIcon.ContextMenu.MenuItems.Add("Open Main Window", new EventHandler(OpenMainWindow_Click));
            //notifyIcon.ContextMenu.MenuItems.Add(
            notifyIcon.ContextMenu.MenuItems.Add("Exit", new EventHandler(Exit_Click));
            notifyIcon.Text = "Mimi Douban FM!";

            notifyIcon.Visible = false;
            notifyIcon.Click += new EventHandler(notifyIcon_Click);
            this.StateChanged += new EventHandler(MainWindow_StateChanged);
            this.Closed += new EventHandler(MainWindow_Closed);
        }

        private void setSkin(Skin newSkin)
        {
            currentSkin = newSkin;
            foreach (string key in newSkin.Brushes.Keys)
            {
                Resources[key] = newSkin.Brushes[key];
            }
        }

        private string toTimeFormat(int sec)
        {
            return String.Format("{0:00}:{1:00}", sec / 60, sec % 60);
        }

        #endregion                 
    }
}
